package io.gitee.hefren.hhregistry.cluster;

import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import io.gitee.hefren.hhregistry.beans.HhregsitrySnapshot;
import io.gitee.hefren.hhregistry.http.HttpInvoker;
import io.gitee.hefren.hhregistry.service.impl.HhRegisterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Date 2024/5/22
 * @Author lifei
 */
public class HhregistryServerHealth {

    private static final Logger log = LoggerFactory.getLogger(HhregistryServerHealth.class);

    private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    private long delay = 5_000;

    private final Cluster cluster;

    public HhregistryServerHealth(Cluster cluster) {
        this.cluster = cluster;
    }

    public void checkServerHealth() {
        executor.scheduleWithFixedDelay(()->{
            try {
                // 探活
                checkRegisterAlive();
                // 选主
                doSelectLeader();
                // 从leader上同步数据
                syncSnapshotFromLeader();
            }catch (Exception e) {
                log.error(Throwables.getStackTraceAsString(e));
            }
        }, 0, delay, TimeUnit.MILLISECONDS);
    }

    private void doSelectLeader() {
        new Selection().selectLeader(cluster.getServerList());
    }

    /**
     * 探测注册中心的实例是否正常工作
     */
    private void checkRegisterAlive() {
        cluster.getServerList().parallelStream().forEach(server -> {
            try {
                if (server.equals(cluster.self())) {
                    return;
                }
                Server info = HttpInvoker.getHttp(Strings.lenientFormat("%s/hhregistryController/info", server.getUrl()), Server.class);
                if (Objects.nonNull(info)) {
                    server.setStatus(true);
                    server.setLeader(info.getLeader());
                    server.setVersion(info.getVersion());
                } else {
                    server.setStatus(false);
                    server.setLeader(false);
                }
            } catch (Exception e) {
                server.setStatus(false);
                server.setLeader(false);
            }
        });
    }

    /**
     * 数据快照同步
     */
    private void syncSnapshotFromLeader() {
        log.debug("syncSnapshotFromLeader......");
        if (Objects.nonNull(cluster.self()) && Objects.nonNull(cluster.leader()) && !cluster.self().getLeader() && cluster.self().getVersion() < cluster.leader().getVersion()) {
            log.debug("====> sync snapshot from leader: {}", cluster.leader().getUrl());
            HhregsitrySnapshot snapshot = HttpInvoker.getHttp(Strings.lenientFormat("%s/hhregistryController/snapshot", cluster.leader().getUrl()), HhregsitrySnapshot.class);
            HhRegisterService.restore(snapshot);
        }
    }



}
